package com.yyj.util;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@SuppressWarnings("unchecked")
public class BeanUtils {

    public static <T> T copyBean(Object source, Class<T> clazz) {
        try {
            T target = clazz.getDeclaredConstructor().newInstance();
            for (Field field : source.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                for (Field field1 : clazz.getDeclaredFields()) {
                    field1.setAccessible(true);
                    if (field1.getName().equals(field.getName()) && field.get(source)!=null) {
                        if( field.getType().equals(field1.getType())){
                            field1.set(target, field.get(source));
                            continue;
                        }
                        if(field.getType().equals(Long.class) && field1.getType().equals(String.class) ){
                            field1.set(target,field.get(source)+"");
                            continue;
                        }
                        if(field.getType().equals(String.class) && field1.getType().equals(Long.class) ){
                            field1.set(target,Long.valueOf((String) field.get(source)));
                            continue;
                        }
                        if(field.getType().equals(Integer.class) && field1.getType().equals(String.class) ){
                            field1.set(target,field.get(source)+"");
                            continue;
                        }
                        if(field.getType().equals(String.class) && field1.getType().equals(Integer.class) ){
                            field1.set(target,Integer.valueOf((String) field.get(source)));
                            continue;
                        }
                        if( List.class.isAssignableFrom(field.getType())&&!List.class.isAssignableFrom(field1.getType()) ){
                            field1.set(target,List2Str((List<?>) field.get(source)));
                            continue;
                        }
                        if( List.class.isAssignableFrom(field1.getType()) && !List.class.isAssignableFrom(field.getType())){
                            Type type = field1.getGenericType();
                            ParameterizedType pt = (ParameterizedType) type;
                            Class<?> clazz1 = (Class<?>) pt.getActualTypeArguments()[0];
                            field1.set(target,arrTolist(field.get(source).toString().split(","),clazz1));
                        }

                    }

                }

            }
            return target;
        } catch (Exception e) {
            throw new RuntimeException("copy property error", e);
        }
    }

    public static <T> String List2Str(List<T> list) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i <= list.size() - 1; i++) {
            if (i == list.size() - 1) {
                str.append(list.get(i));
            } else {
                str.append(list.get(i)).append(",");
            }
        }
        return str.toString();
    }

    public static<T> List<T> arrTolist(String[] strings,Class<T>clazz) {
        List<T> list = new ArrayList<>();
        if (!CheckIsNullOrEmptyUtil.isNullOrEmpty(strings)) {
            for (String string : strings) {
                if(Integer.class==clazz){
                    if(!CheckIsNullOrEmptyUtil.isNullOrEmpty(string)){
                        T value = (T) Integer.valueOf(string);
                        list.add(value);
                    }

                }
                if(Long.class==clazz){
                    if(!CheckIsNullOrEmptyUtil.isNullOrEmpty(string)) {
                        T value = (T) Long.valueOf(string);
                        list.add(value);
                    }
                }
                if(String.class==clazz){
                    if(!CheckIsNullOrEmptyUtil.isNullOrEmpty(string)) {
                        T value = (T) string;
                        list.add(value);
                    }
                }
            }

        }
        return list;
    }

    /**
     *
     * @param data
     * @param all
     * @return
     * @param <T>
     */
    public static<T> Map<String,Object> beanToMap(T data, Boolean all)  {
        Map<String, Object> map = new HashMap<>();
        try {
            Class<?> clazz = data.getClass();
            Field[] fields = clazz.getDeclaredFields();
            Class<?> superclass = clazz.getSuperclass();
            if (superclass != null && all) { //获取父类属性
                Field[] declaredFields = superclass.getDeclaredFields();
                for (Field field : declaredFields) {
                    field.setAccessible(true);
                        if(field.getName().equals("page")){
                            for (Field field1 : declaredFields) {
                                if(field1.getName().equals("size")){
                                    field1.setAccessible(true);
                                    int currentPage = Integer.parseInt(field.get(data).toString());
                                    int size = Integer.parseInt(field1.get(data).toString());
                                    map.put(field.getName(),(currentPage-1)*size);
                                }
                            }
                        }else {
                            map.put(field.getName(), field.get(data));
                        }
                    }
            }
            for (Field field : fields) {
                field.setAccessible(true);
                if (CheckIsNullOrEmptyUtil.isNotNullOrEmpty(field.get(data))) {
                    map.put(field.getName(), field.get(data));
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return map;
    }
}
